package com.legendframework.core.dao;

import com.legendframework.core.AbstractLegendPlugin;
import com.legendframework.core.SaveFileName;
import com.legendframework.core.initialization.dao.DataStorageDao;
import com.legendframework.core.initialization.entity.DataStorage;
import com.legendframework.core.dao.enums.DataType;
import com.legendframework.core.dao.exception.DaoException;
import com.legendframework.core.dao.sql.core.JdbcTemplate;
import com.legendframework.core.dao.sql.factory.WhiteDataSourceFactory;
import com.legendframework.core.dao.sql.pool.WhiteDataSource;
import com.legendframework.core.support.lang3.StringUtils;

import java.util.List;
import java.util.Objects;

public class DataSourceManager {

    private final static String urlParam = "?characterEncoding=utf8&allowMultiQueries=true&serverTimezone=UTC&useSSL=false";

    private static DataSourceManager instance;

    private DataResources dataResources;

    public DataResources getDataResources() {
        return dataResources;
    }

    public DataSourceManager(String rootPath , SaveFileName saveFileName) {
        this.dataResources = buildDataResources(rootPath, saveFileName);
    }

    /**
     * 构建数据源参数
     * @param rootPath 服务端插件目录路径
     * @param saveFileName 本插件配置文件目录 取值{@link AbstractLegendPlugin#getSaveFileName()}
     * @return
     */
    private DataResources buildDataResources(String rootPath , SaveFileName saveFileName) {
        String name = saveFileName.getRootConfigDirectoryName();
        if (StringUtils.isNotEmpty(saveFileName.getConfigDirectoryName()) && !StringUtils.equals(saveFileName.getConfigDirectoryName(), saveFileName.getRootConfigDirectoryName())) {
            name += "/"+ saveFileName.getConfigDirectoryName();
        }
        //初始化数据存储配置文件Dao
        DataResources dr = new DataResources();
        dr.setYamlParentPath(rootPath + "/" + name);
        IDao<DataStorage> dataStorageDao = EntityDaoGenerate.getDaoByDaoType(DataStorageDao.class, dr,null,null);
        dr.setYamlParentPath(rootPath + "/" + saveFileName.getRootConfigDirectoryName());
        List<DataStorage> dataStorages = dataStorageDao.selectList(null);
        DataStorage dataStorage;
        if (dataStorages.isEmpty()) {
            dataStorage = new DataStorage();
            dataStorage.setId("1");
            dataStorage.setDataType(DataType.YAML);
            dataStorageDao.insert(dataStorage);
        } else {
            dataStorage = dataStorages.get(0);
        }
        dr.setDataType(dataStorage.getDataType());
        if (dr.getDataType() == DataType.MYSQL && !checkSqlParam(dataStorage)) {
            throw new DaoException("数据库参数配置不完整,请检查 '"+dr.getYamlParentPath()+"/dataStorage.yml' ");
        }
        if (checkSqlParam(dataStorage)) {
            WhiteDataSource whiteDataSource = new WhiteDataSource();
            whiteDataSource.setDriver("com.mysql.jdbc.Driver");
            whiteDataSource.setUrl(StringUtils.join("jdbc:mysql://",dataStorage.getSqlHost()+":"+dataStorage.getSqlPort(),"/mysql",urlParam));
            whiteDataSource.setUsername(dataStorage.getUsername());
            whiteDataSource.setPassword(dataStorage.getPassword());
            whiteDataSource.setInitialSize(1);
            whiteDataSource.setMaxActive(1);
            WhiteDataSource initDataSource = whiteDataSource.init();
            JdbcTemplate jdbcTemplate = new JdbcTemplate(initDataSource,null);
            String sql = "CREATE DATABASE IF NOT EXISTS "+dataStorage.getDatabaseName() + " charset utf8mb4";
            jdbcTemplate.update(sql);
            //销毁数据源
            initDataSource.discard();
            //创建新的数据库
            WhiteDataSource dataSource =
                    WhiteDataSourceFactory.createWhiteDataSource("com.mysql.jdbc.Driver", "jdbc:mysql://" +
                                    Objects.toString(dataStorage.getSqlHost()) +
                                    ":" +
                                    Objects.toString(dataStorage.getSqlPort()) +
                                    "/" +
                                    Objects.toString(dataStorage.getDatabaseName() +
                                            urlParam),
                            dataStorage.getUsername(),
                            dataStorage.getPassword())
                            .init();
            dr.setDataSource(dataSource);
        }
        return dr;
    }

    /**
     * 校验数据库连接参数是否补全
     * @param dataStorage
     * @return
     */
    private boolean checkSqlParam(DataStorage dataStorage){
        return dataStorage != null &&
                StringUtils.isNotEmpty(dataStorage.getSqlHost()) &&
                StringUtils.isNotEmpty(dataStorage.getSqlPort()) &&
                StringUtils.isNotEmpty(dataStorage.getDatabaseName()) &&
                StringUtils.isNotEmpty(dataStorage.getUsername()) &&
                StringUtils.isNotEmpty(dataStorage.getPassword());
    }

}
